using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;

namespace Leap
{
	public class FingerList : Interface, IEnumerable<Finger>, IEnumerable
	{
		private class FingerListEnumerator : IEnumerator<Finger>, IDisposable, IEnumerator
		{
			private FingerList _list;

			private int _index;

			public Finger Current => _list._operator_get(_index);

			object IEnumerator.Current
			{
				get
				{
					return Current;
				}
			}

			public FingerListEnumerator(FingerList list)
			{
				_list = list;
				_index = -1;
			}

			public void Reset()
			{
				_index = -1;
			}

			public bool MoveNext()
			{
				_index++;
				return _index < _list.Count;
			}

			public void Dispose()
			{
			}
		}

		private HandleRef swigCPtr;

		public Finger this[int index]
		{
			get
			{
				return _operator_get(index);
			}
		}

		public int Count => LeapPINVOKE.FingerList_Count_get(swigCPtr);

		public bool IsEmpty => LeapPINVOKE.FingerList_IsEmpty_get(swigCPtr);

		public Finger Leftmost
		{
			get
			{
				IntPtr intPtr = LeapPINVOKE.FingerList_Leftmost_get(swigCPtr);
				return (intPtr == IntPtr.Zero) ? null : new Finger(intPtr, true);
			}
		}

		public Finger Rightmost
		{
			get
			{
				IntPtr intPtr = LeapPINVOKE.FingerList_Rightmost_get(swigCPtr);
				return (intPtr == IntPtr.Zero) ? null : new Finger(intPtr, true);
			}
		}

		public Finger Frontmost
		{
			get
			{
				IntPtr intPtr = LeapPINVOKE.FingerList_Frontmost_get(swigCPtr);
				return (intPtr == IntPtr.Zero) ? null : new Finger(intPtr, true);
			}
		}

		public FingerList(IntPtr cPtr, bool cMemoryOwn)
			: base(LeapPINVOKE.FingerList_SWIGUpcast(cPtr), cMemoryOwn)
		{
			swigCPtr = new HandleRef(this, cPtr);
		}

		public static HandleRef getCPtr(FingerList obj)
		{
			return obj?.swigCPtr ?? new HandleRef(null, IntPtr.Zero);
		}

		~FingerList()
		{
			Dispose();
		}

		public override void Dispose()
		{
			lock (this)
			{
				if (swigCPtr.Handle != IntPtr.Zero)
				{
					if (base.swigCMemOwn)
					{
						base.swigCMemOwn = false;
						LeapPINVOKE.delete_FingerList(swigCPtr);
					}
					swigCPtr = new HandleRef(null, IntPtr.Zero);
				}
				GC.SuppressFinalize(this);
				base.Dispose();
			}
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return GetEnumerator();
		}

		public IEnumerator<Finger> GetEnumerator()
		{
			return new FingerListEnumerator(this);
		}

		public FingerList()
			: this(LeapPINVOKE.new_FingerList(), true)
		{
		}

		private Finger _operator_get(int index)
		{
			return new Finger(LeapPINVOKE.FingerList__operator_get(swigCPtr, index), true);
		}

		public FingerList Append(FingerList other)
		{
			FingerList result = new FingerList(LeapPINVOKE.FingerList_Append(swigCPtr, getCPtr(other)), false);
			if (LeapPINVOKE.SWIGPendingException.Pending)
			{
				throw LeapPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}

		public FingerList Extended()
		{
			return new FingerList(LeapPINVOKE.FingerList_Extended(swigCPtr), true);
		}

		public FingerList FingerType(Finger.FingerType type)
		{
			return new FingerList(LeapPINVOKE.FingerList_FingerType(swigCPtr, (int)type), true);
		}
	}
}
